
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Write a new PixieDust Visualization &#8212; PixieDust Documentation</title>
    <link rel="stylesheet" href="_static/better.css" type="text/css" />
    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
    <link rel="stylesheet" href="_static/custom.css" type="text/css" />
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    './',
        VERSION:     '1.0',
        COLLAPSE_INDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true,
        SOURCELINK_SUFFIX: '.txt'
      };
    </script>
    <script type="text/javascript" src="_static/jquery.js"></script>
    <script type="text/javascript" src="_static/underscore.js"></script>
    <script type="text/javascript" src="_static/doctools.js"></script>
    <link rel="shortcut icon" href="_static/pd_icon.ico"/>
    <link rel="index" title="Index" href="genindex.html" />
    <link rel="search" title="Search" href="search.html" />
    <link rel="next" title="Build a Renderer" href="renderer.html" />
    <link rel="prev" title="Contribute" href="contribute.html" />
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  </head>
  <body>
    <header id="pageheader"><h1><a href="index.html ">
        PixieDust Documentation
    </a></h1></header>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body" role="main">
            
  <div class="section" id="write-a-new-pixiedust-visualization">
<h1>Write a new PixieDust Visualization<a class="headerlink" href="#write-a-new-pixiedust-visualization" title="Permalink to this headline">¶</a></h1>
<p>Create your own visualizations or apps using the PixieDust extensibility APIs. If you know HTML and CSS, you can write and deliver amazing graphics without forcing notebook users to type one line of code. Use the shape of the data to control when PixieDust shows your visualization in a menu.</p>
<p>When a notebook user invokes <code class="docutils literal"><span class="pre">display()</span></code>, PixieDust provides a chrome that include a toolbar of menus. Each menu is a way to visualize or perform action on the data.</p>
<p>PixieDust framework builds that menu based on introspecting the data itself and associating it with components that the developer declares can process that data.  PixieDust comes with a set of visualizations and actions out-of-the-box, but you can easily add your own custom plugin.</p>
<div class="section" id="quickstart">
<h2>QuickStart<a class="headerlink" href="#quickstart" title="Permalink to this headline">¶</a></h2>
<p>To get started fast, try our generator, which lets you create a sample visualization by answering a few prompts in Terminal or other command line app.</p>
<ol class="arabic simple">
<li>In Terminal or other command-line shell, navigate to the directory where you want to create the new project. This can be anywhere you choose.</li>
<li>Enter and run:</li>
</ol>
<blockquote>
<div><code class="docutils literal"><span class="pre">jupyter</span> <span class="pre">pixiedust</span> <span class="pre">generate</span></code></div></blockquote>
<ol class="arabic" start="3">
<li><p class="first">Respond to the questions/prompts to complete setup. Here’s the entire exchange including the command you’ll run in Step 4:</p>
<img alt="_images/generate_vis.png" src="_images/generate_vis.png" />
</li>
<li><p class="first">Install your new visualization.</p>
<p>If you’re not already there, cd into your project directory and run the following command:</p>
<p><code class="docutils literal"><span class="pre">pip</span> <span class="pre">install</span> <span class="pre">-e</span> <span class="pre">.</span></code></p>
</li>
<li><p class="first">Go to your notebook, and restart the kernel.</p>
</li>
<li><p class="first">Run the command <code class="docutils literal"><span class="pre">import</span> <span class="pre">pixiedust</span></code></p>
</li>
<li><p class="first">Run the command <code class="docutils literal"><span class="pre">import</span> <span class="pre">Sampleviz</span></code>  (or whatever you named your project)</p>
</li>
<li><p class="first">Then load some data and run the display() command on it.</p>
</li>
<li><p class="first">In the charts dropdown, choose a chart you specified that the renderer can display.</p>
</li>
<li><p class="first">Click the <strong>Renderer</strong> dropdown.</p>
</li>
</ol>
<blockquote>
<div><p>You see your new visualization menu item! Here’s one named <strong>Sampleviz</strong>:</p>
<img alt="_images/sample_viz_menu.png" src="_images/sample_viz_menu.png" />
</div></blockquote>
<p>Explore the code in your new project directory. We’ve commented in some guidance that should help you understand what you’re looking at.</p>
</div>
<div class="section" id="code-walk-through-display-a-dataframe-as-a-table">
<h2>Code walk-through: Display a DataFrame as a table<a class="headerlink" href="#code-walk-through-display-a-dataframe-as-a-table" title="Permalink to this headline">¶</a></h2>
<p>Here’s a run-down of what goes into a PixieDust visualization:</p>
<div class="section" id="hook-into-the-display-menu">
<h3>Hook into the display menu<a class="headerlink" href="#hook-into-the-display-menu" title="Permalink to this headline">¶</a></h3>
<p>First, for a user to invoke a graph or visualization, it must appear on the PixieDust menu.</p>
<div class="section" id="class-tabledisplaymeta">
<h4>class TableDisplayMeta<a class="headerlink" href="#class-tabledisplaymeta" title="Permalink to this headline">¶</a></h4>
<p>The first thing you’ll want to do is get your tool presented in the menu. Since you’re building a tool to display a DataFrame as an HTML table, look at <code class="docutils literal"><span class="pre">display/table/__init__.py</span></code>:</p>
<blockquote>
<div><div class="highlight-default"><div class="highlight"><pre><span></span><span class="nd">@PixiedustDisplay</span><span class="p">(</span><span class="n">isDefault</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">TableDisplayMeta</span><span class="p">(</span><span class="n">DisplayHandlerMeta</span><span class="p">):</span>
  <span class="nd">@addId</span>
  <span class="k">def</span> <span class="nf">getMenuInfo</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">entity</span><span class="p">,</span> <span class="n">dataHandler</span><span class="p">):</span>
      <span class="k">if</span> <span class="n">dataFrameMisc</span><span class="o">.</span><span class="n">isPySparkDataFrame</span><span class="p">(</span><span class="n">entity</span><span class="p">)</span> <span class="ow">or</span> <span class="n">dataFrameMisc</span><span class="o">.</span><span class="n">isPandasDataFrame</span><span class="p">(</span><span class="n">entity</span><span class="p">):</span>
          <span class="k">return</span> <span class="p">[</span>
              <span class="p">{</span><span class="s2">&quot;categoryId&quot;</span><span class="p">:</span> <span class="s2">&quot;Table&quot;</span><span class="p">,</span> <span class="s2">&quot;title&quot;</span><span class="p">:</span> <span class="s2">&quot;DataFrame Table&quot;</span><span class="p">,</span> <span class="s2">&quot;icon&quot;</span><span class="p">:</span> <span class="s2">&quot;fa-table&quot;</span><span class="p">,</span> <span class="s2">&quot;id&quot;</span><span class="p">:</span> <span class="s2">&quot;dataframe&quot;</span><span class="p">}</span>
          <span class="p">]</span>
      <span class="k">elif</span> <span class="n">dataFrameMisc</span><span class="o">.</span><span class="n">fqName</span><span class="p">(</span><span class="n">entity</span><span class="p">)</span> <span class="o">==</span> <span class="s2">&quot;graphframes.graphframe.GraphFrame&quot;</span><span class="p">:</span>
          <span class="k">return</span> <span class="p">[</span>
              <span class="p">{</span><span class="s2">&quot;categoryId&quot;</span><span class="p">:</span> <span class="s2">&quot;Table&quot;</span><span class="p">,</span> <span class="s2">&quot;title&quot;</span><span class="p">:</span> <span class="s2">&quot;Graph Vertices&quot;</span><span class="p">,</span> <span class="s2">&quot;icon&quot;</span><span class="p">:</span> <span class="s2">&quot;fa-location-arrow&quot;</span><span class="p">,</span> <span class="s2">&quot;id&quot;</span><span class="p">:</span><span class="s2">&quot;vertices&quot;</span><span class="p">},</span>
              <span class="p">{</span><span class="s2">&quot;categoryId&quot;</span><span class="p">:</span> <span class="s2">&quot;Table&quot;</span><span class="p">,</span> <span class="s2">&quot;title&quot;</span><span class="p">:</span> <span class="s2">&quot;Graph Edges&quot;</span><span class="p">,</span> <span class="s2">&quot;icon&quot;</span><span class="p">:</span> <span class="s2">&quot;fa-link&quot;</span><span class="p">,</span> <span class="s2">&quot;id&quot;</span><span class="p">:</span><span class="s2">&quot;edges&quot;</span><span class="p">}</span>
         <span class="p">]</span>
      <span class="k">else</span><span class="p">:</span>
          <span class="k">return</span> <span class="p">[]</span>
  <span class="k">def</span> <span class="nf">newDisplayHandler</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">options</span><span class="p">,</span><span class="n">entity</span><span class="p">):</span>
      <span class="k">return</span> <span class="n">TableDisplay</span><span class="p">(</span><span class="n">options</span><span class="p">,</span><span class="n">entity</span><span class="p">)</span>
</pre></div>
</div>
</div></blockquote>
<p>Here you see that class <code class="docutils literal"><span class="pre">TableDisplayMeta</span></code> does 2 things. In the method <code class="docutils literal"><span class="pre">getMenuInfo</span></code>, it decides what menus to load, depending on the type of entity passed. In the method <code class="docutils literal"><span class="pre">newDisplayHandler</span></code>, it does the actual data processing.</p>
</div>
<div class="section" id="def-getmenuinfo">
<h4>def getMenuInfo<a class="headerlink" href="#def-getmenuinfo" title="Permalink to this headline">¶</a></h4>
<p>In the <code class="docutils literal"><span class="pre">getMenuInfo</span></code> method of class <code class="docutils literal"><span class="pre">TableDisplayMeta</span></code> you check for the type of the entity. Pixiedust currently supports <code class="docutils literal"><span class="pre">GraphFrame</span></code> and <code class="docutils literal"><span class="pre">PySparkDataFrame</span></code> (currently only 2-dimensional matrix Pandas DataFrames are supported, so you can consider them to be the same as <code class="docutils literal"><span class="pre">PySparkDataFrame</span></code> for the purposes of Pixiedust development).</p>
<p>If it’s a Pandas or PySpark DataFrame, return an array of menu definition objects. A menu definition object consists of 4 properties:</p>
<ol class="arabic simple">
<li><code class="docutils literal"><span class="pre">categoryId</span></code>: a unique string that identifies the menu “category” or group</li>
<li><code class="docutils literal"><span class="pre">title</span></code>: an arbitrary string that describes the menu</li>
<li><code class="docutils literal"><span class="pre">icon</span></code>: the name of a fontawesome icon, or a URL for an image</li>
<li><code class="docutils literal"><span class="pre">id</span></code>: a unique string that identifies your tool</li>
</ol>
<p>PixieDust only has one option for displaying a DataFrame as a table, so you return a single menu object in the array.</p>
</div>
<div class="section" id="def-newdisplayhandler">
<h4>def newDisplayHandler<a class="headerlink" href="#def-newdisplayhandler" title="Permalink to this headline">¶</a></h4>
<p>The other method you must implement is <code class="docutils literal"><span class="pre">newDisplayHandler</span></code>, which is called when the menu item is selected. This is where the DataFrame is actually processed. In this case, return a new <code class="docutils literal"><span class="pre">TableDisplay</span></code> object, which does all the heavy lifting that we’ll talk about next.</p>
</div>
</div>
<div class="section" id="data-processing">
<h3>Data Processing<a class="headerlink" href="#data-processing" title="Permalink to this headline">¶</a></h3>
<blockquote>
<div><p>The <code class="docutils literal"><span class="pre">TableDisplay</span></code> class is defined in <code class="docutils literal"><span class="pre">display/table/display.py</span></code>. You can <a class="reference external" href="https://gist.github.com/rajrsingh/67e45a1c0ecc64207a189501d9559ea5">see the code on GitHub</a>.</p>
<blockquote>
<div><div class="highlight-default"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">TableDisplay</span><span class="p">(</span><span class="n">Display</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">doRender</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">handlerId</span><span class="p">):</span>
        <span class="n">entity</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">entity</span>
        <span class="k">if</span> <span class="n">dataFrameMisc</span><span class="o">.</span><span class="n">fqName</span><span class="p">(</span><span class="n">entity</span><span class="p">)</span> <span class="o">==</span> <span class="s2">&quot;graphframes.graphframe.GraphFrame&quot;</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">handlerId</span> <span class="o">==</span> <span class="s2">&quot;edges&quot;</span><span class="p">:</span>
                <span class="n">entity</span><span class="o">=</span><span class="n">entity</span><span class="o">.</span><span class="n">edges</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">entity</span><span class="o">=</span><span class="n">entity</span><span class="o">.</span><span class="n">vertices</span>
        <span class="k">if</span> <span class="n">dataFrameMisc</span><span class="o">.</span><span class="n">isPySparkDataFrame</span><span class="p">(</span><span class="n">entity</span><span class="p">)</span> <span class="ow">or</span> <span class="n">dataFrameMisc</span><span class="o">.</span><span class="n">isPandasDataFrame</span><span class="p">(</span><span class="n">entity</span><span class="p">):</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">_addHTMLTemplate</span><span class="p">(</span><span class="s1">&#39;dataframeTable.html&#39;</span><span class="p">,</span> <span class="n">entity</span><span class="o">=</span><span class="n">PandasDataFrameAdapter</span><span class="p">(</span><span class="n">entity</span><span class="p">))</span>
            <span class="k">return</span>

        <span class="bp">self</span><span class="o">.</span><span class="n">_addHTML</span><span class="p">(</span><span class="s2">&quot;&quot;&quot;</span>
<span class="s2">            &lt;b&gt;Unable to display object&lt;/b&gt;</span>
<span class="s2">        &quot;&quot;&quot;</span>
        <span class="p">)</span>
</pre></div>
</div>
</div></blockquote>
</div></blockquote>
<p>This class must implement one method, <code class="docutils literal"><span class="pre">doRender</span></code>, which is called with a reference to <code class="docutils literal"><span class="pre">self</span></code> and a <code class="docutils literal"><span class="pre">handlerId</span></code>. In the case of DataFrame display, the <code class="docutils literal"><span class="pre">handlerId</span></code> is unused, so you only need to check for one DataFrame entity type. You can display it using a <a class="reference external" href="http://jinja.pocoo.org/">Jinja2</a> HTML template.</p>
</div>
<div class="section" id="html-rendering-with-jinja2">
<h3>HTML rendering with Jinja2<a class="headerlink" href="#html-rendering-with-jinja2" title="Permalink to this headline">¶</a></h3>
<p>This line of code:</p>
<p><code class="docutils literal"><span class="pre">self._addHTMLTemplate('dataframeTable.html',</span> <span class="pre">entity=PandasDataFrameAdapter(entity))</span></code></p>
<p>is the key to rendering our data. <code class="docutils literal"><span class="pre">dataframeTable.html</span></code> (by default found in the templates directory in the same directory as the calling file) is a Jinja2 template consisting of CSS styles, HTML and data processing language. You should study this file carefully <a class="reference external" href="https://gist.github.com/rajrsingh/8bdfe8ac7b87f442640f85292b1aab82">here</a>, but the key lines are:</p>
<ol class="arabic simple">
<li><code class="docutils literal"><span class="pre">{%</span> <span class="pre">set</span> <span class="pre">rows</span> <span class="pre">=</span> <span class="pre">entity.take(100)</span> <span class="pre">%}</span></code>: get the first 100 lines of the DataFrame and assign to variable <code class="docutils literal"><span class="pre">rows</span></code></li>
<li><code class="docutils literal"><span class="pre">{%</span> <span class="pre">for</span> <span class="pre">field</span> <span class="pre">in</span> <span class="pre">entity.getFields()</span> <span class="pre">%}</span></code>: loop over the fields and display each as a <code class="docutils literal"><span class="pre">&lt;th&gt;</span></code></li>
<li><code class="docutils literal"><span class="pre">{%</span> <span class="pre">for</span> <span class="pre">row</span> <span class="pre">in</span> <span class="pre">rows</span> <span class="pre">%}</span></code>: loop over the rows and display each as a <code class="docutils literal"><span class="pre">&lt;tr&gt;</span></code></li>
</ol>
<p>Also note the <code class="docutils literal"><span class="pre">&lt;script&gt;</span></code> tag at the end of the file. This is where you can do some nifty extras like scrolling while keeping the table header in a fixed position and client-side search.</p>
</div>
</div>
<div class="section" id="build-your-own-table-display-plugin">
<h2>Build your own table display plugin<a class="headerlink" href="#build-your-own-table-display-plugin" title="Permalink to this headline">¶</a></h2>
<p>Now that you’ve seen how PixieDust works, let’s build a very simple second table display tool. You’ll need to do 3 things:</p>
<p>1. Add a menu item and hook it to your code
3. Transform the DataFrame into something a web browser can display (HTML in our case, but it could be SVG, a PDF or something more exotic) using Jinja2 HTML templating</p>
<div class="section" id="add-a-menu-item-and-hook-it-to-your-code">
<h3>Add a menu item and hook it to your code<a class="headerlink" href="#add-a-menu-item-and-hook-it-to-your-code" title="Permalink to this headline">¶</a></h3>
<p>Have PixieDust recognize your new menu item code by adding this line in the imports of <code class="docutils literal"><span class="pre">__init__.py</span></code> (in the directory <code class="docutils literal"><span class="pre">display/table</span></code>):</p>
<p><code class="docutils literal"><span class="pre">from</span> <span class="pre">.SimpleDisplayMeta</span> <span class="pre">import</span> <span class="pre">SimpleDisplayMeta</span></code></p>
<p>Then create the file SimpleDisplayMeta.py and enter this code:</p>
<blockquote>
<div><div class="highlight-default"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">.SimpleDisplay</span> <span class="k">import</span> <span class="n">SimpleDisplay</span>
<span class="kn">from</span> <span class="nn">..display</span> <span class="k">import</span> <span class="o">*</span>
<span class="kn">import</span> <span class="nn">pixiedust.utils.dataFrameMisc</span> <span class="k">as</span> <span class="nn">dataFrameMisc</span>

<span class="nd">@PixiedustDisplay</span><span class="p">()</span>
<span class="k">class</span> <span class="nc">SimpleDisplayMeta</span><span class="p">(</span><span class="n">DisplayHandlerMeta</span><span class="p">):</span>
   <span class="nd">@addId</span>
   <span class="k">def</span> <span class="nf">getMenuInfo</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">entity</span><span class="p">,</span><span class="n">dataHandler</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">dataFrameMisc</span><span class="o">.</span><span class="n">isPySparkDataFrame</span><span class="p">(</span><span class="n">entity</span><span class="p">)</span> <span class="ow">or</span> <span class="n">dataFrameMisc</span><span class="o">.</span><span class="n">isPandasDataFrame</span><span class="p">(</span><span class="n">entity</span><span class="p">):</span>
           <span class="k">return</span> <span class="p">[</span>
               <span class="p">{</span><span class="s2">&quot;categoryId&quot;</span><span class="p">:</span> <span class="s2">&quot;Table&quot;</span><span class="p">,</span> <span class="s2">&quot;title&quot;</span><span class="p">:</span> <span class="s2">&quot;Simple Table&quot;</span><span class="p">,</span> <span class="s2">&quot;icon&quot;</span><span class="p">:</span> <span class="s2">&quot;fa-table&quot;</span><span class="p">,</span> <span class="s2">&quot;id&quot;</span><span class="p">:</span> <span class="s2">&quot;simpleTest&quot;</span><span class="p">}</span>
           <span class="p">]</span>
        <span class="k">else</span><span class="p">:</span>
      <span class="k">return</span> <span class="p">[]</span>
   <span class="k">def</span> <span class="nf">newDisplayHandler</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">options</span><span class="p">,</span><span class="n">entity</span><span class="p">):</span>
       <span class="k">return</span> <span class="n">SimpleDisplay</span><span class="p">(</span><span class="n">options</span><span class="p">,</span><span class="n">entity</span><span class="p">)</span>
</pre></div>
</div>
</div></blockquote>
<p>As described earlier, the method <code class="docutils literal"><span class="pre">getMenuInfo</span></code> provides the hook to add a menu item to the user interface. You specify “Table” as the <code class="docutils literal"><span class="pre">categoryID</span></code> to add this tool to the existing Table menu. Give it any <cite>title</cite> and <code class="docutils literal"><span class="pre">icon</span></code> you want. And finally, give it a unique id, such as “simpleTest”.</p>
<p>The <code class="docutils literal"><span class="pre">newDisplayHandler</span></code> method specifies the code used to do the data processing work. That looks like this:</p>
</div>
<div class="section" id="dataframe-html">
<h3>DataFrame =&gt; HTML<a class="headerlink" href="#dataframe-html" title="Permalink to this headline">¶</a></h3>
<p>Create the file SimpleDisplay.py in the directory <cite>display/table</cite>, and enter this code:</p>
<blockquote>
<div><div class="highlight-default"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">..display</span> <span class="k">import</span> <span class="o">*</span>
<span class="kn">from</span> <span class="nn">pyspark.sql</span> <span class="k">import</span> <span class="n">DataFrame</span>
<span class="kn">from</span> <span class="nn">pixiedust.utils.dataFrameAdapter</span> <span class="k">import</span> <span class="o">*</span>
<span class="kn">import</span> <span class="nn">pixiedust.utils.dataFrameMisc</span> <span class="k">as</span> <span class="nn">dataFrameMisc</span>

<span class="k">class</span> <span class="nc">SimpleDisplay</span><span class="p">(</span><span class="n">Display</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">doRender</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">handlerId</span><span class="p">):</span>
        <span class="n">entity</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">entity</span>
        <span class="k">if</span> <span class="n">dataFrameMisc</span><span class="o">.</span><span class="n">isPySparkDataFrame</span><span class="p">(</span><span class="n">entity</span><span class="p">)</span> <span class="ow">or</span> <span class="n">dataFrameMisc</span><span class="o">.</span><span class="n">isPandasDataFrame</span><span class="p">(</span><span class="n">entity</span><span class="p">):</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">_addHTMLTemplate</span><span class="p">(</span><span class="s1">&#39;simpleTable.html&#39;</span><span class="p">,</span> <span class="n">entity</span><span class="o">=</span><span class="n">PandasDataFrameAdapter</span><span class="p">(</span><span class="n">entity</span><span class="p">))</span>
            <span class="k">return</span>

        <span class="bp">self</span><span class="o">.</span><span class="n">_addHTML</span><span class="p">(</span><span class="s2">&quot;&quot;&quot;</span>
<span class="s2">            &lt;b&gt;Unable to display object&lt;/b&gt;</span>
<span class="s2">        &quot;&quot;&quot;</span>
        <span class="p">)</span>
</pre></div>
</div>
</div></blockquote>
<p>All you’re really doing here is defining a mechanism to call the right Jinja template – <code class="docutils literal"><span class="pre">simpleTable.html</span></code> found in the <code class="docutils literal"><span class="pre">templates</span></code> directory – for processing the data. Once you’re working on the template, the sky’s the limit for what you can do. But just to finish out this example, here’s some extremely simple code you can add there:</p>
<blockquote>
<div><div class="highlight-default"><div class="highlight"><pre><span></span><span class="o">&lt;</span><span class="n">table</span> <span class="n">class</span><span class="o">=</span><span class="s2">&quot;table table-striped&quot;</span><span class="o">&gt;</span>
   <span class="o">&lt;</span><span class="n">thead</span><span class="o">&gt;</span>
       <span class="p">{</span><span class="o">%</span><span class="k">for</span> <span class="n">field</span> <span class="ow">in</span> <span class="n">entity</span><span class="o">.</span><span class="n">schema</span><span class="o">.</span><span class="n">fields</span><span class="o">%</span><span class="p">}</span>
       <span class="o">&lt;</span><span class="n">th</span><span class="o">&gt;</span><span class="p">{{</span><span class="n">field</span><span class="o">.</span><span class="n">name</span><span class="p">}}</span><span class="o">&lt;/</span><span class="n">th</span><span class="o">&gt;</span>
       <span class="p">{</span><span class="o">%</span><span class="n">endfor</span><span class="o">%</span><span class="p">}</span>
   <span class="o">&lt;/</span><span class="n">thead</span><span class="o">&gt;</span>
   <span class="o">&lt;</span><span class="n">tbody</span><span class="o">&gt;</span>
       <span class="p">{</span><span class="o">%</span><span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">entity</span><span class="o">.</span><span class="n">take</span><span class="p">(</span><span class="mi">100</span><span class="p">)</span><span class="o">%</span><span class="p">}</span>
       <span class="o">&lt;</span><span class="n">tr</span><span class="o">&gt;</span>
           <span class="p">{</span><span class="o">%</span><span class="k">for</span> <span class="n">field</span> <span class="ow">in</span> <span class="n">entity</span><span class="o">.</span><span class="n">schema</span><span class="o">.</span><span class="n">fields</span><span class="o">%</span><span class="p">}</span>
           <span class="o">&lt;</span><span class="n">td</span><span class="o">&gt;</span><span class="p">{{</span><span class="n">row</span><span class="p">[</span><span class="n">field</span><span class="o">.</span><span class="n">name</span><span class="p">]}}</span><span class="o">&lt;/</span><span class="n">td</span><span class="o">&gt;</span>
           <span class="p">{</span><span class="o">%</span><span class="n">endfor</span><span class="o">%</span><span class="p">}</span>
       <span class="o">&lt;/</span><span class="n">tr</span><span class="o">&gt;</span>
       <span class="p">{</span><span class="o">%</span><span class="n">endfor</span><span class="o">%</span><span class="p">}</span>
   <span class="o">&lt;/</span><span class="n">tbody</span><span class="o">&gt;</span>
<span class="o">&lt;/</span><span class="n">table</span><span class="o">&gt;</span>
</pre></div>
</div>
</div></blockquote>
<div class="section" id="what-you-get">
<h4>What you get<a class="headerlink" href="#what-you-get" title="Permalink to this headline">¶</a></h4>
<p>Now that the code is complete. Let’s update PixieDust in our notebook and see the results. Shut down your Jupyter environment, run the below command from your terminal, and restart Jupyter to get the new code.</p>
<p><code class="docutils literal"><span class="pre">pip</span> <span class="pre">install</span> <span class="pre">--user</span> <span class="pre">-e</span> <span class="pre">&lt;your</span> <span class="pre">directory</span> <span class="pre">path</span> <span class="pre">to</span> <span class="pre">pixiedust</span> <span class="pre">code&gt;</span></code></p>
<p>You should now see something resembling the screenshot below. The table menu is now a dropdown with two options, <strong>DataFrame Table</strong> and your new <strong>Simple Table</strong>. Choosing <strong>Simple Table</strong> displays the data using the template you defined in simpleTable.html!</p>
<img alt="_images/pixiedustnewtableoption.png" src="_images/pixiedustnewtableoption.png" />
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">PixieDust provides a higher level framework built on top of the <code class="docutils literal"><span class="pre">display()</span></code> API that lets you contribute more tightly to the chart menus. When you use the renderer API you contribute to the list renderers that can display a particular type of chart. For example, let notebook users choose Mapbox to display a map. At the lowest level you can create only a visualization and don’t need to specify a renderer. But if you’re interested in learning more, read how to <a class="reference external" href="renderer.html">build a renderer</a>.</p>
</div>
</div>
</div>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
<h3><a href="index.html">Table Of Contents</a></h3>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="use.html">Use PixieDust</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="develop.html">Develop for PixieDust</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="contribute.html">Contribute</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">Write a new PixieDust Visualization</a></li>
<li class="toctree-l2"><a class="reference internal" href="renderer.html">Build a Renderer</a></li>
<li class="toctree-l2"><a class="reference internal" href="test.html">Test</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="pixieapps.html">PixieApps</a></li>
<li class="toctree-l1"><a class="reference internal" href="pixiegateway.html">PixieGateway</a></li>
<li class="toctree-l1"><a class="reference internal" href="releasenotes.html">Release Notes</a></li>
</ul>

<div id="searchbox" style="display: none" role="search">
  <h3>Quick search</h3>
    <form class="search" action="search.html" method="get">
      <div><input type="text" name="q" /></div>
      <div><input type="submit" value="Go" /></div>
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
  <footer id="pagefooter">&copy; 2017, IBM.
      Created using <a href="http://sphinx-doc.org/">Sphinx</a>
      1.6.3.

  </footer>

  
  </body>
</html>